package com.itstyle.seckill.topic.jichu;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Auther: liuwenxiang
 * @Date: 2020/4/14 23:38
 * @Description:
 */
public class ConditionTest {


    private Object[] b;

    //添加标示，删除标示，队列实际大小
    private int  addindex,removeindex,count;

    private Lock lock= new ReentrantLock();

    /**
     * 1。等待队列是基于同步状态获取
     * 2。可以每个Condition管理一类线程
     */
    private Condition empty = lock.newCondition();

    private Condition full = lock.newCondition();

    public ConditionTest(int size){
        b = new Object[size];
    }

    public <T> void add(T t){
        lock.lock();
        try {
            /**
             * 此处不用if，就是当线程满的时候，就算唤醒了，也无法向下执行。
             * 加await，就不需要一直自旋了,且可以"释放锁"--不需要显示的释放
             */
            while(b.length==count){
                System.out.println("await");
                full.await();
            }
            addindex++;
            if(addindex==b.length){
                addindex=0;//队列添加标示用完
            }
            count++;//队列添加元素记录（count会随着队列增删而变化，但是数组添加元素和移除元素都是自增，自减的）
            b[addindex]=t;
            empty.signal();//唤醒标示空的等待队列
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            System.out.println(Thread.currentThread().getName()+"=="+b.length);
            lock.unlock();
        }
    }

    public <T> T remove(T t){
        System.out.println("remove1=="+b.length);
        lock.lock();
        System.out.println("remove2=="+b.length);
        try {
            //当队列为空的时候，线程就在为空的等待队列休息
            while(b.length==0){
                empty.wait();
            }
            Object x= b[removeindex];
            if(++removeindex==b.length){
                removeindex=0;
            }
            --count;
            full.signal();
            return (T)x;
        }catch(InterruptedException e){
            e.printStackTrace();
        }finally {
            System.out.println("remove3=="+b.length);
            lock.unlock();
        }
        return t;
    }

    public static void main(String[] args) {
        ConditionTest conditionTest=new ConditionTest(1);
        new Thread(new Runnable(){

            @Override
            public void run() {
                conditionTest.add(1);
            }
        }).start();

        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(new Runnable(){

            @Override
            public void run() {
                conditionTest.add(2);
            }
        }).start();

        try {
            TimeUnit.SECONDS.sleep(13);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


        new Thread(new Runnable(){

            @Override
            public void run() {
                conditionTest.remove(2);
            }
        }).start();


    }

}
